package com.caigou.component;

import com.caigou.bean.cms.entity.Article;
import com.caigou.bean.cms.entity.ChannelData;
import com.caigou.mapper.cms.ArticleMapper;
import com.caigou.mapper.cms.ChannelDataMapper;
import gui.ava.html.image.generator.HtmlImageGenerator;
import lombok.extern.slf4j.Slf4j;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.select.Elements;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.util.ObjectUtils;

import javax.annotation.Resource;
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.awt.image.MemoryImageSource;
import java.awt.image.PixelGrabber;
import java.io.*;
import java.nio.charset.StandardCharsets;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

@Slf4j
@Component
public class HtmlBuildImageComponent {

    @Value("${domain}")
    private String domain;
    @Value("${webRoot}")
    private String webRoot;

    @Resource
    private ArticleMapper articleMapper;
    @Resource
    private ChannelDataMapper channelDataMapper;

    @Resource
    private HtmlDetailBuilderComponent htmlDetailBuilderComponent;

    public void buildImageByHtmlStr(String articleId, String articleContent){
        try {
            // 获取文本信息解析HTML文本
            Article article = articleMapper.loadArticle(articleId);
            // 截取文本内容
            String sensitive = "";
            Pattern pattern = Pattern.compile("<article .*>.*<.article>",Pattern.DOTALL + Pattern.MULTILINE);
            Matcher matcher = pattern.matcher(articleContent);
            if (matcher.find()) {
                log.info("匹配到需要的内容提供");
                sensitive = matcher.group(0);
            }
            if (!sensitive.equals("")){
                // 过滤掉html文本中的自定义样式
                String regEx_style="<style[^>]*?>[\\s\\S]*?<\\/style>"; //定义style的正则表达式
                sensitive = sensitive.replaceAll(regEx_style,"");
                // TODO: 2020/12/8 0008 图片、音频、视频处理
                // 剔除音/视频样式
                String regEx_video = "<p><video controls .*><\\/video><\\/p>";
                String regEx_audio = "<p><div class=\\\"audio_wrap\\\">.*?<\\/div><\\/p>";
                sensitive = sensitive.replaceAll(regEx_video, "").replaceAll(regEx_audio, "");// 去除VIDEO/AUDIO标签
                String regEx_video2 = "<video .*><\\/video>";
                String regEx_audio2 = "<audio .*><\\/audio>";
                sensitive = sensitive.replaceAll(regEx_video2, "").replaceAll(regEx_audio2, "");// 去除原生VIDEO/AUDIO标签
                Pattern pattern1 = Pattern.compile("(<img .*?\\/>)",Pattern.DOTALL + Pattern.MULTILINE);
                // 处理图片
                Matcher matcher1 = pattern1.matcher(sensitive);
                StringBuffer buffer1 = new StringBuffer() ;
                while (matcher1.find()) {
                    String tmp = matcher1.group().toLowerCase();
                    String v = "<p>"+tmp+"</p>";
                    matcher1.appendReplacement(buffer1, v) ;
                }
                matcher1.appendTail(buffer1) ;
                Pattern pattern2 = Pattern.compile("<img", Pattern.DOTALL + Pattern.MULTILINE);
                Matcher matcher2 = pattern2.matcher(buffer1.toString());
                StringBuffer buffer2 = new StringBuffer();
                while (matcher2.find()){
                    String tmp = matcher2.group().toLowerCase();
                    String v = tmp+" width='750' height='500'";
                    matcher2.appendReplacement(buffer2, v) ;
                }
                matcher2.appendTail(buffer2);
                sensitive = buffer2.toString();
                // 剔除空格符
                sensitive = sensitive.replaceAll("&nbsp;","");
                // 进行图片生成处理
                HtmlImageGenerator imageGenerator = new HtmlImageGenerator();
                String html = "<html>" +
                        "<head>" +
                        "<meta charset='UTF-8'>" +
                        "<style type='text/css'>img {width: 750px; height: auto;}</style>" +
                        "</head>" +
                        "<body>" +
                        "<table width='750' cellpadding='28'>" +
                        "<tr><td colspan='2' align='center'>" +
                        "<img src='https://testwww.caigou2003.com/web/img/long-weibo-logo.png' style='width: 750px;'/>" +
                        "</td></tr>" +
                        "<tr><td colspan='2' style='padding-top: 18px;'>" +
                        "<h1 style='font-size: 38px;font-weight: bold;'>" +
                        article.getArticleTitle() +
                        "</h1></td></tr>" +
                        "<tr><td colspan='2' style='padding-top: 0px; padding-bottom: 0px;'>" +
                        sensitive +
                        "</td></tr>" +
                        "<tr>" +
                        "<td colspan='2' align='center'>" +
                        "<img src='https://testwww.caigou2003.com/web/img/long-weibo-qrcode.png' style='width: 750px;'/>" +
                        "</td>" +
                        "</tr>" +
                        "</table>" +
                        "</body>" +
                        "</html>";
                imageGenerator.loadHtml(html);// 加载HTML字符串
                imageGenerator.getBufferedImage();// 生成图片字符流
                int imageCount = localImg(html);
                Thread.sleep(600 * imageCount);
                // 根据文中图片数量进行休眠等待
                String urlPath = "/web/";
                Date date = article.getCreateTime();
                SimpleDateFormat sdf1 = new SimpleDateFormat("yyyyMMdd");

                String fileFolder = webRoot+urlPath+sdf1.format(date)+"/";
                // 判断文件夹是否存在(如果不存在进行创建)
                File folder = new File(fileFolder);
                if (!folder.exists())
                    folder.mkdirs();// 如果当前文件夹不存在--创建新的文件夹
                // 生成图片
                imageGenerator.saveAsImage(fileFolder+articleId+".png");// 保存图片
                // 获取静态图片地址更新文章主表字段
                String imageUrl = domain+urlPath+sdf1.format(date)+"/"+articleId+".png";
                articleMapper.updateArticleShareUrl(articleId,imageUrl);
                // 获取当前文章除RSS频道以外发布的最早的记录--如果没有记录则更新RSS频道，如果有则更新最早的数据
                ChannelData channelData = channelDataMapper.loadLastChannelData(articleId);
                if (null == channelData) {
                    htmlDetailBuilderComponent.buildArticleHtml(articleId, "999");
                } else {
                    htmlDetailBuilderComponent.buildArticleHtml(articleId, channelData.getPlateId());
                }
            }
        } catch (Exception e){
            e.printStackTrace();
        }
    }

    private static Integer localImg(String content) {
        Document document = Jsoup.parseBodyFragment(content);
        if (ObjectUtils.isEmpty(document)) return 0;
        Elements elements = document.body().getElementsByTag("img");
        return elements.size();
    }

    private static void updateImage(String inPath, String outPath) throws IOException{

        InputStream inputStream = new FileInputStream(new File(inPath));

        BufferedImage bufferedImage = ImageIO.read(inputStream);

        int height = bufferedImage.getHeight(); //图片的高
        int width = bufferedImage.getWidth();  //图片的宽

        int newHeight =0;
        int newWidth =0;
        //
        if(1024 >width){
            double s = 1024 /width;
            newHeight = (int) ((int) height*s);
            newWidth = (int) ((int) width*s);
        }
        if(1024 <width){
            double s = width/ 1024;
            newHeight = (int) ((int) height/s);
            newWidth = (int) ((int) width/s);
        }

        BufferedImage image = new BufferedImage(newWidth,newHeight, BufferedImage.TYPE_INT_BGR);

        Graphics graphics = image.createGraphics();
        graphics.drawImage(bufferedImage, 0, 0, newWidth, newHeight, null);

        OutputStream outputStream = new FileOutputStream(new File(outPath));

        /* image为处理后的图片，jpeg为图片编码格式，out为输出流 */
        ByteArrayOutputStream jpegOutputStream = new ByteArrayOutputStream();
        ImageIO.write(image,"png",jpegOutputStream);
        //byteArrayOutputStream输出到file
        outputStream.write(jpegOutputStream.toByteArray());
        outputStream.close();
    }
}
